跳到主要内容

MySQL 学习(7)自适应哈希索引和异步 IO

自适应哈希索引是什么?

哈希(hash)是一种非常快的查找方法,在一般情况下这种查找的时间复杂度为 O(1)O(1) ,即一般仅需要一次查找就能定位数据。 而 B+ 树的查找次数,取决于 B+ 树的高度,在生产环境中,B+ 树的高度一般为 3~4 层,所以需要 3~4 次的查询。

InnoDB 存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引(Adaptive Hash Index, AHI)。

AHI 是通过缓冲池的 B+ 树页构造而来,因此建立的速度很快,而且不需要对整张表构建哈希索引。InnoDB 存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。

自适应哈希的建立条件

AHI 有一个要求,对这个页的连续访问模式必须是一样的。例如对于 (a,b) 这样的联合索引页,其访问模式可以是下面情况:

where a = xxx
where a = xxx and b=xxx

访问模式一样是指查询的条件是一样的,若交替进行上述两种查询,那么 InnoDB 存储引擎不会对该页构造 AHI。 AHI 还有下面几个要求:

  • 以该模式访问了 100 次
  • 页通过该模式访问了 N 次,其中 N = 页中记录 * 1/16

InnoDB 存储引擎官方文档显示,启用 AHI 后,读取和写入速度可以提高 2 倍,辅助索引的连接操作性能可以提高 5 倍。AHI 的设计思想是数据库自优化,不需要 DBA 对数据库进行手动调整。

异步 IO

为了提高磁盘操作性能,当前的数据库系统都采用异步 IO(AsynchronousI0,AIO)的方式来处理磁盘操作。InnoDB 存储引擎亦是如此。

与 AIO 对应的是 SyncIO,即每进行一次I0操作,即每进行一次 IO 操作,此次操作结束才能继续接下来的操作。

但是如果用户发需要等待出一条索引扫描的查询,那么这条 SQL 查询语句可能需要扫描多个索引页,也就是需要进行多次的 IO 操作。在每扫描一个页并等待期完成再进行下一次的扫描是没有必要的。

用户可以在发出一个 IO 请求后立即再发出另一个 IO 请求,当全部 IO 请求发送完毕后,等待所有 IO 操作的完成,这就是 AIO。

AIO另一个优势可以将多个IO,合并为1个IO,以提高IO效率。例如:用户需要访问 3 页内容,但这 3 页时连续的。同步 IO 需要进行 3 次 IO,而 AIO 只需要一次就可以了。

刷新领接页

当刷新一个脏页时,innodb 会检测该页所在区(extent)的所有页,如果是脏页,那么一起进行刷新。这样做,通过 AIO 将多个 IO 写入操作合并为一个 IO 操作。在传统机械磁盘下有着显著优势。